﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RayDen.Library.Components;
using RayDen.Library.Components.Surface;
using RayDen.Library.Data.Import.OBJLoader;
using RayDen.Library.Entity.Scene;
using RayDen.MaterialManager.Controls;
using RayDen.RayEngine.Materials;

namespace RayDen.MaterialManager
{
    public class ApplicationController
    {

        public static ApplicationController Instance { get; protected set; }
        public string CurrentDirectory;
        public MaterialVault CurrentVault;

        public BindingList<string> Materials
        {
            get { return new BindingList<string>(this.CurrentVault.Select(GetMaterialName).ToList()); }
        }

       
        public ApplicationController()
        {            
            CurrentVault = new MaterialVault();
            var def = ConfigurationManager.AppSettings.Get("DefaultVault");
            if (File.Exists(def))
            {
                CurrentVault.LoadXml(def, this.KnownTypes);

            }
            EditorsBootstraper.AppStarted = true;
            Instance = this;
        }

        public void OpenMtl(string mtlPath)
        {
            var mtl = new MaterialLoader();
            var mats = mtl.LoadMaterials(mtlPath);
            var lib = new BsdfLibrary();
            lib.Populate(mats);
            foreach (var mat in lib)
            {
                CurrentVault.Add(mat.Name, mat);
            }
            this.CurrentDirectory = Path.GetDirectoryName(mtlPath);
        }

        public void SaveVault(string fn)
        {
            CurrentVault.SaveXml(fn, KnownTypes);
        }

        public void OpenVault(string fn)
        {
            CurrentVault.LoadXml(fn, KnownTypes);
        }

        private static string GetMaterialName(SurfaceMaterial mt)
        {
            return string.Format("[{0}]_|_<{1}>", mt.First!=null ? mt.First.GetType().Name :"Empty", mt.Name);
        }


        public Type[] KnownTypes { get
        {
            return new []
                {
                    typeof(MatteMaterial),
                    typeof(MatteMirrorMaterial),
                    typeof(GlassMaterial),
                    typeof(ArchGlassMaterial),
                    typeof(MetalMaterial),
                    typeof(AlloyMaterial),
                    typeof(DistributionBsdf),
                    typeof(MirrorMaterial),

                    typeof(ImageTextureInfo),
                    typeof(ConstTextureInfo),
                    typeof(SolidTextureInfo),

                    typeof(Dictionary<string, SurfaceMaterial>),
                    typeof(MaterialVault),

                    typeof(SurfaceMaterial),
                };
        } }

        internal void AddMaterial()
        {
            this.CurrentVault.Add("NewMaterial", new SurfaceMaterial());
        }
    }
}
